#!/usr/bin/env bash
#
# Automated Arch Linux Installer by iknski
# --------------------------------------------------------------------
# Author    : iknski
# License   : GNU GPLv2 (https://www.gnu.org/licenses/old-licenses/gpl-2.0.html)
# Version   : v 2.0
# --------------------------------------------------------------------
# 23.05.2024
#
clear
loadkeys ru
setfont cyr-sun16
BLINK="\033[5m"
BLACK="\033[0;30m"
RED="\033[0;31m"
LRED="\033[1;31m"
GREEN="\033[0;32m"
LGREEN="\033[1;32m"
BLUE="\033[0;34m"
LBLUE="\033[1;34m"
WHITE="\033[0;37m"
LWHITE="\033[1;37m"
NORMAL="\033[0m"
#
echo -en "
 ____ ____ ____ ____ ______________ ____ ____ ____ ____ ____ ____ ____
||A |||R |||C |||H |||    from    |||I |||N |||S |||T |||A |||L |||L ||
||__|||__|||__|||__|||___iknski___|||__|||__|||__|||__|||__|||__|||__||
|/__\|/__\|/__\|/__\|/____________\|/__\|/__\|/__\|/__\|/__\|/__\|/__\|

----------------------------------------------------------------------
| Внимание!!!
| Этот скрипт автоматически установит ${LBLUE}Arch Linux${NORMAL} на ваш компьютер
| Скрипт создан исключительно для UEFI API и SSD дисков
| Для установки понадобится интернет соединение
----------------------------------------------------------------------
"
sleep 3
timedatectl set-ntp true
pacman -S --noconfirm archlinux-keyring
pacman -S --noconfirm --needed pacman-contrib
clear
#
echo -en "======================================================================\n"
echo -en ">>>                           ВЫБОР ДИСКА                          <<<\n"
echo -en "======================================================================\n"
lsblk -o NAME,LABEL,UUID,FSTYPE,MOUNTPOINTS
echo -en "----------------------------------------------------------------------\n"
echo -en "| Введите имя диска на который хотите установить ${LBLUE}Arch Linux\n${NORMAL}"
echo -en "| (возможные варианты: sda, nvme0n1, и. т. д.)\n"
echo -en "----------------------------------------------------------------------\n"
#-------
# получаем список блочных устройств пользователя
blocks=()
for item in $(ls /sys/class/block); do
    blocks+=("${item}")
done
#-------
# проверка пользователя на ошибочный ввод блочного устройства
for item in "${blocks[@]}"; do
    read -r -p "| Установить Arch Linux на -> /dev/. >>> " archdisk
    if [[ "${blocks[*]}" =~ "${archdisk}" ]]; then
        echo "| Ваш выбор: ${archdisk}"
        break
    else
        echo "| ${archdisk} - нет такого диска, попробуйте ввести снова ..."
        continue
    fi
done
#-------
while true; do
    echo -en "----------------------------------------------------------------------\n"
    echo -en "| ${RED}Внимание!!! Данные на устройстве /dev/${archdisk} будут УДАЛЕНЫ!!!\n${NORMAL}"
    echo -en "| ${GREEN}Если хотите остановить выполнение скрипта, выберите - No\n${NORMAL}"
    echo -en "| Продолжить установку системы?\n"
    echo -en "----------------------------------------------------------------------\n"
    read -r -p "| Yes/No (Y/N) >>> " user_answer
    case ${user_answer} in
    Yes | YES | yes | Yep | YEP | yep | Y | y)
        echo -en "----------------------------------------------------------------------\n"
        source $(dirname $0)/parted-helper
        unset user_answer
        break
        ;;
    No | NO | no | Nope | NOPE | nope | N | n | "")
        echo "| Работа скрипта завершена..."
        unset user_answer
        sleep 1
        clear
        exit
        ;;
    *)
        echo "| Неверный ввод, попробуйте снова..."
        continue
        ;;
    esac
done
#-------
source $(dirname $0)/fs-helper
#-------
# чем я руководствовался при составлении шаблона разметки диска
# https://wiki.archlinux.org/title/Partitioning
# https://wiki.archlinux.org/title/EFI_system_partition
# https://uapi-group.org/specifications/specs/boot_loader_specification/#the-partitions
mkfs.vfat -F32 -n ESP /dev/${partition1} &>/dev/null
mkfs.vfat -F32 -n BOOT /dev/${partition2} &>/dev/null
mount /dev/${partition1} /mnt/efi
mount /dev/${partition2} /mnt/boot
echo -en "----------------------------------------------------------------------\n"
lsblk -o NAME,LABEL,UUID,FSTYPE,MOUNTPOINTS
echo -en "----------------------------------------------------------------------\n"
echo -en "| Диск подготовлен для установки...\n"
read -r -sn1 -p "| Нажмите любую клавишу чтобы продолжить..."
#-------
clear
echo -en "----------------------------------------------------------------------\n"
echo -en "| Создайте имя компьютера\n"
echo -en "----------------------------------------------------------------------\n"
while true
do
    read -r -p "| Ввести имя компьютера >>> " hostnm
    # проверка корректного названия компьютера
    if [[ "${hostnm,,}" =~ ^[a-z][a-z0-9_.-]{0,62}[a-z0-9]$ ]]; then
        break
    fi
    read -p "| Такое имя некорректно. Уверены что хотите его оставить? (Y/N)" user_answer
    if [[ "${user_answer,,}" = "y" ]]; then
        unset user_answer
        break
    fi
done
#-------
echo -en "----------------------------------------------------------------------\n"
echo -en "| Создайте пароль для юзера ${RED}root\n${NORMAL}"
#-------
source $(dirname $0)/keygen-helper
rootpsw="${password}"
unset password
#-------
echo -en "----------------------------------------------------------------------\n"
echo -en "| Создайте своего пользователя\n"
echo -en "----------------------------------------------------------------------\n"
while true
do
    read -r -p "| Ввести имя пользователя >>> " usernm
    echo -en "----------------------------------------------------------------------\n"
    # проверка корректного имени пользователя
    # https://unix.stackexchange.com/questions/157426/what-is-the-regex-to-validate-linux-users
    if [[ "${usernm,,}" =~ ^[a-z_]([a-z0-9_-]{0,31}|[a-z0-9_-]{0,30}\$)$ ]]; then
        break
    fi
    echo "| Некорректное имя пользователя..."
done
usernm=${usernm,,}
echo -en "| Создайте пароль для пользователя ${GREEN}${usernm}\n${NORMAL}"
source $(dirname $0)/keygen-helper
userpsw="${password}"
unset password
clear
#-------
echo -en "======================================================================\n"
echo -en ">>>                   Настройка часового пояса                     <<<\n"
echo -en "======================================================================\n"
while true
do
    read -p "Хотите ли определить ваше местоположение автоматически? (Y/N)" user_answer
    if [[ "${user_answer,,}" = "y" ]]; then
        time_zone="$(curl --fail https://ipapi.co/timezone)"
        echo -en "\n"
		echo -en "**************************************************\n"
        echo -en "| Ваше местоположение: ${GREEN}${time_zone}\n${NORMAL}"
		echo -en "**************************************************\n"
		echo -en "\n"
        unset user_answer
        sleep 1
        break
    else
        echo -en "----------------------------------------------------------------------\n"
        echo -en "| Введите ваш регион обязательно с заглавной буквы в формате (Europe/Moscow, America/Chicago...)\n"
        echo -en "----------------------------------------------------------------------\n"
        read -r -p "| Ввести местоположение >>> " time_zone
        echo -en "----------------------------------------------------------------------\n"
        unset user_answer
        break
    fi
done
#-------
echo -en "----------------------------------------------------------------------\n"
echo -en "| Определение вендора вашего процессора (amd или intel...)\n"
echo -en "----------------------------------------------------------------------\n"
proc_type=$(lscpu)
if grep -E "GenuineIntel" <<< ${proc_type} &>/dev/null; then
    echo -en "\n"
    echo -en "**************************************************\n"
    echo -en "| Ваш $(grep -E "GenuineIntel" <<< ${proc_type})\n| Будет установлен ${LBLUE}Intel microcode\n${NORMAL}"
    echo -en "\n"
    echo -en "**************************************************\n"
    proc_ucode=intel-ucode
elif grep -E "AuthenticAMD" <<< ${proc_type} &>/dev/null; then
    echo -en "\n"
    echo -en "**************************************************\n"
    echo -en "| Ваш $(grep -E "AuthenticAMD" <<< ${proc_type})\n| Будет установлен ${LRED}AMD microcode\n${NORMAL}"
    echo -en "**************************************************\n"
    echo -en "\n"
    proc_ucode=amd-ucode
fi
sleep 3
clear
#-------
echo -en "----------------------------------------------------------------------\n"
echo -en "| Небольшие подготовительные процедуры...\n"
echo -en "----------------------------------------------------------------------\n"
timedatectl set-ntp true
timedatectl set-timezone ${time_zone}
#-------
source $(dirname $0)/net-helper
#-------
# https://wiki.archlinux.org/title/Xorg/Keyboard_configuration
mkdir -p /mnt/etc/X11/xorg.conf.d
touch /mnt/etc/X11/xorg.conf.d/00-keyboard.conf
#-------
echo -en "----------------------------------------------------------------------\n"
echo -en "| Установка ${LBLUE}Arch Linux...\n${NORMAL}"
echo -en "----------------------------------------------------------------------\n"
source $(dirname $0)/install-helper
install $(dirname $0)/pkgs/base.txt
install $(dirname $0)/pkgs/driver.txt
pacstrap -K /mnt ${proc_ucode} --noconfirm
echo -en "----------------------------------------------------------------------\n"
echo -en "| ${LBLUE}Arch Linux${NORMAL} установлен...\n"
echo -en "| Генерируем таблицу файловой системы...\n"
echo -en "----------------------------------------------------------------------\n"
genfstab -U /mnt >>/mnt/etc/fstab
cat /mnt/etc/fstab
sleep 3
#-------
# твик компилятора
ncpu=$(grep -c ^processor /proc/cpuinfo)
TOTAL_MEM=$(cat /proc/meminfo | grep -i 'memtotal' | grep -o '[[:digit:]]*')
if [[  ${TOTAL_MEM} -gt 8000000 ]]; then
sed -i "s/#MAKEFLAGS=\"-j2\"/MAKEFLAGS=\"-j${ncpu}\"/g" /mnt/etc/makepkg.conf
sed -i "s/COMPRESSXZ=(xz -c -z -)/COMPRESSXZ=(xz -c -T ${ncpu} -z -)/g" /mnt/etc/makepkg.conf
fi
#-------
echo -en "| Настриваем локали...\n"
echo -en "----------------------------------------------------------------------\n"
arch-chroot /mnt /bin/bash -c "sed -i '/^#en_US.UTF-8/s/^.//' /etc/locale.gen"
sed -i '/^#ru_RU.UTF-8/s/^.//' /etc/locale.gen
arch-chroot /mnt /bin/bash -c "sed -i '/^#ru_RU.UTF-8/s/^.//' /etc/locale.gen"
arch-chroot /mnt /bin/bash -c "locale-gen"
arch-chroot /mnt /bin/bash -c "echo 'LANG=ru_RU.UTF-8' > /etc/locale.conf"
{
    echo "KEYMAP=ru"
    echo "FONT=cyr-sun16"
} >>/mnt/etc/vconsole.conf
# Общесистемные настройки клавиатуры
# https://wiki.archlinux.org/title/Xorg/Keyboard_configuration
echo -en "| Настриваем раскладку клавиатуры (смена раскладки при нажатии ${LRED}CAPS_LOCK...${NORMAL})\n"
echo -en "----------------------------------------------------------------------\n"
{
    echo "Section \"InputClass\""
    echo "    Identifier \"system-keyboard\""
    echo "    MatchIsKeyboard \"on\""
    echo "    Option \"XkbLayout\" \"us,ru\""
    echo "    Option \"XkbModel\" \"pc105\""
    echo "    Option \"XkbOptions\" \"grp:caps_toggle\""
    echo "EndSection"
} >>/mnt/etc/X11/xorg.conf.d/00-keyboard.conf
sleep 1
#-------
echo -en "----------------------------------------------------------------------\n"
echo -en "| Синхронизируем время...\n"
echo -en "----------------------------------------------------------------------\n"
arch-chroot /mnt /bin/bash -c "ln -sf /usr/share/zoneinfo/${time_zone} /etc/localtime"
arch-chroot /mnt /bin/bash -c "hwclock --systohc"
sleep 1
#-------
echo -en "| Применяем настройки хоста...\n"
echo -en "----------------------------------------------------------------------\n"
arch-chroot /mnt /bin/bash -c "echo '${hostnm}' > /etc/hostname"
{
    echo "127.0.0.1	localhost"
    echo "::1		localhost"
    echo "127.0.1.1	${hostnm}.localdomain	${hostnm}"
} >>/mnt/etc/hosts
sleep 1
#-------
echo -en "| Устанавливаем нужные для файловой системы пакеты...\n"
echo -en "----------------------------------------------------------------------\n"
if [[ "${fs_type}" = "1" ]]; then
    pacstrap -K /mnt btrfs-progs ntfs-3g --noconfirm --needed
    sed -i '/^BINARIES/s/\(.\)$/btrfs)/' /mnt/etc/mkinitcpio.conf
else
    pacstrap -K /mnt e2fsprogs ntfs-3g --noconfirm --needed
fi
#-------
install $(dirname $0)/pkgs/additional.txt
install $(dirname $0)/pkgs/cmd.txt
install $(dirname $0)/pkgs/xorg.txt
install $(dirname $0)/pkgs/wayland.txt
install $(dirname $0)/pkgs/pipewire.txt
#-------
echo -en "----------------------------------------------------------------------\n"
echo -en "| Устанавливаем графические драйверы...\n"
echo -en "----------------------------------------------------------------------\n"
source $(dirname $0)/graphics-helper
#-------
echo -en "----------------------------------------------------------------------\n"
echo -en "| Конфигурируем юзеров (root и ${usernm})...\n"
echo -en "----------------------------------------------------------------------\n"
echo "root:${rootpsw}" | arch-chroot /mnt chpasswd
arch-chroot /mnt /bin/bash -c "useradd -m -G wheel,audio,video,storage -s /bin/bash ${usernm}"
arch-chroot /mnt /bin/bash -c "export EDITOR=micro"
echo "${usernm}:${userpsw}" | arch-chroot /mnt chpasswd
arch-chroot /mnt /bin/bash -c "sed -i '/^# %wheel ALL=(ALL:ALL) ALL/s/^..//' /etc/sudoers"
sleep 1
#-------
echo -en "| Настраиваем интернет...\n"
echo -en "----------------------------------------------------------------------\n"
success=("Yes" "YES" "yes" "Yep" "YEP" "yep" "Y" "y")
if [[ "${success[*]}" =~ "${cpnt_settings}" ]]; then
    pacstrap -K /mnt iwd --noconfirm
    {
        echo "[General]"
        echo "EnableNetworkConfiguration=true"
        echo ""
        echo "[Network]"
        echo "EnableIPv6=true"
        echo "RoutePriorityOffset=600"
    } >>/mnt/etc/iwd/main.conf
    arch-chroot /mnt /bin/bash -c "systemctl enable systemd-networkd.service"
    arch-chroot /mnt /bin/bash -c "systemctl enable systemd-resolved.service"
    arch-chroot /mnt /bin/bash -c "systemctl enable iwd.service"
else
    pacstrap -K /mnt iwd networkmanager nm-connection-editor network-manager-applet --noconfirm
    arch-chroot /mnt /bin/bash -c "systemctl enable NetworkManager.service"
    arch-chroot /mnt /bin/bash -c "systemctl enable iwd.service"
fi
sleep 1
#-------
echo -en "----------------------------------------------------------------------\n"
echo -en "| Запускаем нужные сервисы...\n"
echo -en "----------------------------------------------------------------------\n"
arch-chroot /mnt /bin/bash -c "systemctl enable sshd.service"
arch-chroot /mnt /bin/bash -c "systemctl enable fstrim.timer"
arch-chroot /mnt /bin/bash -c "systemctl enable reflector.timer"
arch-chroot /mnt /bin/bash -c "systemctl enable systemd-timesyncd.service"
arch-chroot /mnt /bin/bash -c "systemctl enable --user pipewire-pulse.service"
sleep 1
#-------
echo -en "| Настраиваем pacman...\n"
echo -en "----------------------------------------------------------------------\n"
sed -i '/^#Color/s/^.//' /mnt/etc/pacman.conf
sed -i '/^#VerbosePkgLists/s/^.//' /mnt/etc/pacman.conf
sed -i '/^#ParallelDownloads = 5/s/^.//' /mnt/etc/pacman.conf
sed -i "/\[multilib\]/,/Include/"'s/^#//' /mnt/etc/pacman.conf
arch-chroot /mnt /bin/bash -c "pacman -Syy"
arch-chroot /mnt /bin/bash -c "reflector --verbose --country 'Russia,Germany,' --latest 5 --sort rate --save /etc/pacman.d/mirrorlist"
arch-chroot /mnt /bin/bash -c "sed -i s/'--country France,Germany'/'--country Russia,Germany'/g /etc/xdg/reflector/reflector.conf"
arch-chroot /mnt /bin/bash -c "sed -i s/'--sort age'/'--sort rate'/g /etc/xdg/reflector/reflector.conf"
sleep 1
#-------
install $(dirname $0)/pkgs/boot_tools.txt
#-------
source $(dirname $0)/boot-helper
#-------
source $(dirname $0)/profile-helper
#-------
unset archdisk
unset proc_ucode
unset partition1
unset partition2
unset partition3
unset partition4
unset fs_type
unset clvl
unset gpu_type
unset gen_choice
unset again_choise
unset pass_len
unset cpnt_settings
unset success
# unset tool_type
unset boot_type
unset home_type
unset UUID
unset profile_type
#-------
echo -en "----------------------------------------------------------------------\n"
echo -en "| Arch Linux установлен и настроен...\n"
echo -en "| Пожалуйста выполните << umount -a >> и << reboot >> для загрузки в новую систему!!!\n"
echo -en "----------------------------------------------------------------------\n"
